#ifndef __WIZ_DATATYPE_COLOR_HPP__SHANHAOBO_19800429__
#define __WIZ_DATATYPE_COLOR_HPP__SHANHAOBO_19800429__

#include "../../Base/Type/WizBaseType.hpp"
#include "../../Base/Cast/WizBaseCast.hpp"

#include "./WizDataTypeColorUInt32.hpp"

namespace Wiz
{
    //////////////////////////////////////////////////////////////////////////
    namespace Color
    {
        class WIZ_EXPORT Type
        {
            WIZ_DECLARE_CLASS_THIS(Type);
        public:
            ::Wiz::Real::Type r, g, b, a;
        public:
            Type();
            Type(
                ::Wiz::Real::In red,
                ::Wiz::Real::In green,
                ::Wiz::Real::In blue,
                ::Wiz::Real::In alpha = 1
                );
            //////////////////////////////////////////////////////////////////////////
        public:
            ::Wiz::Void::Type Saturate();
        public:
            ::Wiz::Void::Type From(
                ::Wiz::UInt8::In    red,
                ::Wiz::UInt8::In    green,
                ::Wiz::UInt8::In    blue,
                ::Wiz::UInt8::In    alpha
                );
            ::Wiz::Void::Type FromRGBA(::Wiz::UInt32::In color);
            ::Wiz::Void::Type FromARGB(::Wiz::UInt32::In color);
            ::Wiz::Void::Type FromABGR(::Wiz::UInt32::In color);
            ::Wiz::Void::Type FromBGRA(::Wiz::UInt32::In color);

            ////////////////////////////////////////////////////////////////////
            /// TO
            ::Wiz::Void::Type To(
                ::Wiz::UInt8::Out    red,
                ::Wiz::UInt8::Out    green,
                ::Wiz::UInt8::Out    blue,
                ::Wiz::UInt8::Out    alpha
                ) const;
            ::Wiz::UInt32::Type ToRGBA() const;
            ::Wiz::UInt32::Type ToARGB() const;
            ::Wiz::UInt32::Type ToABGR() const;
            ::Wiz::UInt32::Type ToBGRA() const;

            //////////////////////////////////////////////////////////////////////////

            friend WIZ_INLINE tThisRef operator+= (tThisOut Out1, tThisIn In2)
            {
                Out1.r += In2.r; 
                Out1.g += In2.g; 
                Out1.b += In2.b; 
                Out1.a += In2.a; 
                Out1.Saturate();
                return Out1;
            }
            friend WIZ_INLINE tThisRef operator-= (tThisOut Out1, tThisIn In2)
            {
                Out1.r -= In2.r; 
                Out1.g -= In2.g; 
                Out1.b -= In2.b; 
                Out1.a -= In2.a; 
                Out1.Saturate();
                return Out1;
            }
            friend WIZ_INLINE tThisRef operator*= (tThisOut Out1, ::Wiz::Real::In InT)
            {
                Out1.r *= InT; 
                Out1.g *= InT; 
                Out1.b *= InT; 
                Out1.a *= InT; 
                Out1.Saturate();
                return Out1;
            }

            friend WIZ_INLINE tThis operator+ (tThisIn In1, tThisIn In2)
            {
                tThis Temp = In1;
                return Temp += In2;
            }
            friend WIZ_INLINE tThis operator- (tThisIn In1, tThisIn In2)
            {
                tThis Temp = In1;
                return Temp -= In2;
            }
            friend WIZ_INLINE tThis operator* (tThisIn In1, ::Wiz::Real::In InT)
            {
                tThis Temp = In1;
                return Temp *= InT;
            }

            WIZ_INLINE tThisRef operator+()
            {
                return *this;
            }

            WIZ_INLINE const Type& operator+() const
            {
                return *this;
            }

            WIZ_INLINE Type operator-() const
            {
                Type Temp(-r, -g, -b, -a);
                return Temp;
            }

            WIZ_INLINE ::Wiz::Bool::Type operator== (tThisIn In1) const
            {
                return (r == In1.r) && (g == In1.g) && (b == In1.b) && (a == In1.a);
            }
            WIZ_INLINE ::Wiz::Bool::Type operator!= (tThisIn In1) const
            {
                return !operator==(In1);
            }
        };
        WIZ_DECLARE(::Wiz::Color::Type);

        static const ::Wiz::Color::Type Zero  = ::Wiz::Color::Type(0, 0, 0, 0);
        static const ::Wiz::Color::Type Black = ::Wiz::Color::Type(0, 0, 0);
        static const ::Wiz::Color::Type White = ::Wiz::Color::Type(1, 1, 1);
        static const ::Wiz::Color::Type Red   = ::Wiz::Color::Type(1, 0, 0);
        static const ::Wiz::Color::Type Green = ::Wiz::Color::Type(0, 1, 0);
        static const ::Wiz::Color::Type Blue  = ::Wiz::Color::Type(0, 0, 1);
    } /// end of namespace color
    //////////////////////////////////////////////////////////////////////////
} /// end of namespace Wiz

#endif /*__WIZ_DATATYPE_COLOR_HPP__SHANHAOBO_19800429__*/
